package com.linser.gistools.common.property;

import com.linser.gistools.utils.GlobalVariables;

import javax.crypto.*;
import javax.crypto.spec.PBEParameterSpec;
import java.nio.charset.Charset;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.Properties;
import java.util.Base64;

/**
 * @author: linser
 * @Desc:
 * @create: 2024-02-01 10:29
 **/
public class EncryptedPropertiesBase64 extends Properties implements EncryptedPropertiesInterface {
    /** The Constant serialVersionUID. */
    private static final long serialVersionUID = 1L;

    /** The encrypter. */
    private transient Cipher encrypter = null;

    /** The decrypter. */
    private transient Cipher decrypter = null;

    /** The salt. */
    private static byte[] salt = {(byte) 0x03, 0x0F, 0x12, 0x0D, 0x03, 0x0F, 0x12, 0x0D};

    /** Instantiates a new encrypted properties. */
    public EncryptedPropertiesBase64() {
        // Default constructor
    }

    /* (non-Javadoc)
     * @see com.sldeditor.common.property.EncryptedPropertiesInterface#initialise(java.lang.String)
     */
    @Override
    public void initialise(String password) {
        PBEParameterSpec ps = new javax.crypto.spec.PBEParameterSpec(salt, 20);
        SecretKeyFactory kf;
        try {
            kf = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
            SecretKey k =
                    kf.generateSecret(new javax.crypto.spec.PBEKeySpec(password.toCharArray()));
            encrypter = Cipher.getInstance("PBEWithMD5AndDES/CBC/PKCS5Padding");
            decrypter = Cipher.getInstance("PBEWithMD5AndDES/CBC/PKCS5Padding");
            encrypter.init(Cipher.ENCRYPT_MODE, k, ps);
            decrypter.init(Cipher.DECRYPT_MODE, k, ps);
        } catch (NoSuchAlgorithmException
                 | NoSuchPaddingException
                 | InvalidKeySpecException
                 | InvalidKeyException
                 | InvalidAlgorithmParameterException e) {
            //TODO
            //ConsoleManager.getInstance().exception(this, e);
        }
    }

    /* (non-Javadoc)
     * @see com.sldeditor.common.property.EncryptedPropertiesInterface#decrypt(java.lang.String)
     */
    @Override
    public synchronized String decrypt(String str) {
        Charset fileEncoding = Charset.forName(GlobalVariables.commonConfigProperties.getProperty("charset"));

        byte[] dec;
        try {
            dec = Base64.getDecoder().decode(str.getBytes(fileEncoding));
            byte[] utf8 = decrypter.doFinal(dec);
            return new String(utf8, fileEncoding);
        } catch (IllegalBlockSizeException | BadPaddingException e) {
            //TODO
            //ConsoleManager.getInstance().exception(this, e);
        }

        return str;
    }

    /* (non-Javadoc)
     * @see com.sldeditor.common.property.EncryptedPropertiesInterface#encrypt(java.lang.String)
     */
    @Override
    public synchronized String encrypt(String str) {
        byte[] utf8;
        try {
            Charset fileEncoding = Charset.forName(GlobalVariables.commonConfigProperties.getProperty("charset"));

            utf8 = str.getBytes(fileEncoding);
            byte[] enc = encrypter.doFinal(utf8);
            return Base64.getEncoder().encodeToString(enc);
        } catch (IllegalBlockSizeException | BadPaddingException e) {
            //TODO
            //ConsoleManager.getInstance().exception(this, e);
        }

        return "";
    }
}
